home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_200
/
201_01
/
fdires.c
< prev
next >
Wrap
Text File
|
1980-01-01
|
14KB
|
534 lines
/****************************************************************************/
/* */
/* FDIRES.C Version 1.3 3/6/86 Brian Irvine */
/* */
/* Released to the Public Domain for use without profit */
/* */
/****************************************************************************/
/* */
/* fdires.c - Program to demonstrate use of stayres.c in creating a */
/* terminate-and-stay-resident program in DeSmet C. */
/* */
/* This program demonstrates the techniques used to create a */
/* program which will terminate but remain resident as part */
/* of DOS. The program is a sorted directory displayer which */
/* will show a sorted and formatted listing of files on the */
/* current directory. It is supplied mainly to demonstrate */
/* the techniques involved in creating TSR programs. */
/* */
/* The program is activated with the Alt F-10 key. This will */
/* display a sorted listing of the files on the current */
/* directory. The display will remain until a key is pressed. */
/* If the Ctrl F-10 key is pressed, the program will be */
/* removed from memory and you will be returned to DOS. */
/* Do NOT exit this way if you are running FDIRES from within */
/* an application program. You will bomb the computer when */
/* you try to return to your application. Pressing any key */
/* other than Ctrl F-10 will return you to your application. */
/* */
/* The program must be linked with the other module in this */
/* library using the -s option of bind with a stack allowance */
/* of 0x1000 (4096 decimal). This should be more than */
/* adequate for 99% of all applications. */
/* */
/* This code is based in part on a set of routines written by */
/* Lane Ferris et al which are available on the Borland SIG on */
/* Compuserve. */
/* */
/* Brian Irvine */
/* 3379 St Marys Place */
/* Santa Clara, CA 95051 */
/* [71016,544] */
/* */
/****************************************************************************/
/* */
/* Revisions: */
/* version 1.0 - 10/85 */
/* Initial release */
/* */
/* version 1.20 - 3/3/86 */
/* Added code to remove program from memory. */
/* New version of resident code */
/* */
/* version 1.30 - 3/6/86 */
/* Added code to check for program already in memory */
/* */
/****************************************************************************/
#include <stdio.h>
#define KILL_CHAR 255
#define MAX_DIRS 1000
#define KB_INT 0x16
#define DOS_INT 0x21
#define GET_DRV 0x19
#define FILE_NOT_FOUND 2 /* DOS function error codes */
#define INVALID_DRIVE 15
#define NO_MORE_FILES 18
struct {
char reserved[21]; /* disk transfer area */
char attribute;
int time;
int date;
long file_size;
char name[13];
} dta;
struct dir_entry{ /* directory entry */
char e_attribute;
int e_time;
int e_date;
long e_file_size;
char e_name[13];
} entry[MAX_DIRS]; /* enough room for 1000 entries */
long free_space;
long total_space;
int entries = 0;
int _rax, _rbx, _rcx, _rdx, /* variables to hold register values */
_rsi, _rdi, _rds, _res;
int row, column; /* cursor position - must be global */
extern char _carryf;
char label [12];
char pathname [65];
char buffer [65];
static char save_screen[4000]; /* save the screen here */
long get_free ();
extern unsigned old_kbint_off;
extern unsigned old_kbint_seg;
extern int check_dupe(); /* the code to prevent loading program twice */
extern void stayres(); /* the code to terminate and stay resident */
/*----- Main ---------------------------------------------------------------*/
/* */
/* In this application all we have to do is call the tsr code. Other */
/* initialization can be performed here before fencing ourselves off. */
/* */
/*--------------------------------------------------------------------------*/
main ()
{
/* first thing is to check to see if program is already loaded */
if ( check_dupe () )
puts("\nFDIRES is already in memory.\n\n");
else
stayres ();
}
/*----- Main program entry point -------------------------------------------*/
fdir ()
{
char ch;
int n, stat, curr_drv;
int mode;
unsigned screen_seg;
/* get the video mode */
mode = get_mode ();
/* save the user's screen and cursor position */
find_cursor ();
if ( mode == 7 )
screen_seg = 0xB000;
else
screen_seg = 0xB800;
_lmove ( 4000, 0, screen_seg, save_screen, _showds() );
scr_clr ();
scr_rowcol (0,0);
entries = 0;
_setmem (buffer, 65, '\0' ); /* initialize buffers explicitly each */
_setmem (pathname, 65, '\0' ); /* time through because it changes */
if ( get_path () == ERR )
{
puts ("Invalid drive specifier.\n");
exit(1);
}
/* Now construct the path name using current drive */
curr_drv = get_curr_drv ();
buffer[0] = curr_drv + 'A';
buffer[1] = ':';
if ( strlen ( pathname ) == 0 )
buffer[2] = '\0';
else
{
buffer[2] = '\\';
buffer[3] = '\0';
}
strcat ( buffer, pathname );
strcpy ( pathname, buffer );
n = ( 80 - strlen ( pathname ) - 14 ) / 2;
strncpy ( buffer, " ", n);
strcat ( buffer, "Directory of " );
strcat ( buffer, pathname );
printf ( "%s\n\n", buffer );
set_dta ();
/* Get the first matching directory entry */
if ( get_first () )
{
puts ("File not found.\n");
exit (1);
}
/* Now collect all the other matching names */
while ( ( stat = get_next () ) != NO_MORE_FILES )
;
free_space = get_free ();
sort_files ();
print_files ();
/* now put everything back where it was */
puts ("\nPress any key to continue...");
while ( ( ch = scr_csts() ) == 0 )
;
if ( ch == KILL_CHAR ) /* if we want to get rid of the program then */
{
purge(); /* reset the keyboard vector and free memory */
exit(0);
}
else
{
_lmove ( 4000, save_screen, _showds(), 0, screen_seg );
scr_rowcol ( row, column );
}
}
/*----- Kill the resident program ------------------------------------------*/
void purge ()
{
unsigned psp, envptr;
psp = _showcs() - 0x10;
_lmove(2, 0x2C, psp, &envptr, _showds());
puts ("\n\nFDIRES terminated. Urghhh...\n\n");
/* reset the keyboard interrupt service vector */
_rds = old_kbint_seg;
_rdx = old_kbint_off;
_rax = 0x2500 + KB_INT;
_doint ( DOS_INT );
/* free up the program memory */
_rax = 0x4900;
_res = psp; /* point to beginning of PSP for EXE file */
_doint ( DOS_INT );
/* free up the environment area */
_rax = 0x4900;
_res = envptr; /* point to environment area */
_doint ( DOS_INT );
}
/*----- Get the current drive number ---------------------------------------*/
int get_curr_drv ()
{
return ( _os ( GET_DRV, 0 ) );
}
/*----- Get path name of current directory ---------------------------------*/
int get_path ()
{
_rax = 0x4700;
_rdx = 0;
_rsi = &pathname[0];
_rds = _showds();
_doint ( DOS_INT );
if ( _carryf )
return ERR;
}
/*----- Give the DTA address t